﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;

namespace MetMax.Importer
{
    class IsotopeConcentrator : Base
    {
        #region constructors
        public IsotopeConcentrator(MetMaxDataSet.resultDataTable dt, string[] filenames, Options opt)
            : base(dt != null ? dt : new MetMaxDataSet.resultDataTable(), filenames, opt)
        {
        }

        public IsotopeConcentrator(BackgroundWorkerArgument bgwa, Options opt)
            : this(bgwa.dt as MetMaxDataSet.resultDataTable, bgwa.filenames, opt)
        {
        }
        #endregion constructors

        public new MetMaxDataSet.resultDataTable dt
        {
            get { return base.dt as MetMaxDataSet.resultDataTable; }
        }

        public override void Import(string fullFileName, DataColumn currentfileColumn)
        {
            //load the stuff from the file into the memory
            IEnumerable<BusinessObject.Base> resultListCopy = LoadFile(fullFileName).ToList().AsParallel();

            //compute a fitting for the retention time
            IEnumerable<BusinessObject.Base> retentionstandards = (from p in resultListCopy
                                                              where p.RiMarkerRegExMatch.Success
                                                              select p).AsParallel();
            Fitting.Polynomial poly3fit_1stDimension = getPolynomialFittingDegree3Rt1ToAlkaneIndex(retentionstandards);
            
            Fitting.Spline RelativeAlkanRetentionTime = null;
            try
            {
                RelativeAlkanRetentionTime = getRelativeAlkanRetentionTime(retentionstandards);
            }
            catch (Exception)
            {
                //MessageBox.Show(exc.Message);
            } 
            
            Fitting.ObservationPointDictionary ri1system = getRi1System(retentionstandards);
            Fitting.ObservationPointDictionary ri2system = getRi2System(retentionstandards);

            foreach (BusinessObject.Base v in (from p in resultListCopy.AsParallel() select p))
            {
                if (CancellationPending)
                {
                    break;
                }

                IEnumerable<IEnumerable<string>> selectivMetaboliteMasses = from p in opt.dataset.MetaboliteFragments.AsParallel()
                                                               where p.name == v.nameWiped
                                                               select Enumerable.Range(p.fragment_mass_min, p.fragment_mass_max - p.fragment_mass_min + 1).Select(x=>x.ToString());

                if (selectivMetaboliteMasses.Count() != 0)
                {
                    IEnumerable<string> orderedMassSequence = from p in selectivMetaboliteMasses.Aggregate((firstList, secondList) => { return firstList.Concat(secondList); })
                            orderby p ascending
                            select p;

                    foreach (string fragmentMass in orderedMassSequence)
                    {
                        //DataRow tmpRow = this.Rows.Find(new object[] { v.GetName, v.mass.Value });
                        DataRow tmpRow = dt.FindBynamemass(v.nameWiped, fragmentMass);
                        if (tmpRow == null)
                        {
                            tmpRow = dt.AddresultDataTableRow(v.nameWiped, fragmentMass, v.ri.Value);
                        }
                        tmpRow[currentfileColumn] = new BusinessObject.RetentionAnalysis(v, fragmentMass, poly3fit_1stDimension, RelativeAlkanRetentionTime, ri1system, ri2system);
                    }
                }
            }
        }
    }
}
